package Apache;

use strict;
use Data::Dumper;
use MIME::Base64;

sub print_hash_count() {
    my $hash_in = shift;
    my %hash = %{$hash_in};
    my $count = 0;
    printf "#  Count    Value\n" if not $main::fileflag;
    printf $main::outfile localtime() . "    #  Count    Value\n" if $main::fileflag;
    foreach my $key ( sort { $hash{$b} <=> $hash{$a} } keys %hash) {
        $count += 1;
        printf "%-2d %-8d $key\n", ($count, $hash{$key}) if not $main::fileflag;
        printf $main::outfile localtime() . "    %-2d: %-8d $key\n", ($count, $hash{$key}) if $main::fileflag;
        if ( $count == 10 ) {
            last;
        }
    }
}

#Author: Ian McCown
#Apache Log Project part 1
sub connections () {
    my $access_log = defined $main::access_log ? 
        $main::access_log : $main::logdir . "access_log";
    open ACCESSFILE, "<", $access_log or die "access_log not found at [$access_log]\n\n";
    while (<ACCESSFILE>) {
        $_ =~ / - -/;
        $main::connections{$`} += 1;
    }
    close ACCESSFILE;

    &print_hash_count(\%main::connections);
}



#Author: Ian McCown
#Apache Log Project part 2

sub browsers () {
    my $access_log = defined $main::access_log ? 
        $main::access_log : $main::logdir . "audit_log";
    open ACCESSFILE, "<", $access_log or die "access_log not found at [$access_log]\n\n";
    while (<ACCESSFILE>) {
        $_ =~ /CONNECT .*".*" /;
        my $b_key = $';
        chomp($b_key);
        if (not $b_key eq ""){
            $main::browsers{$b_key} += 1;
        }
    }
    close ACCESSFILE;

    &print_hash_count(\%main::browsers);
}


#Author: Jeff Bean
#Apache Log Project part 3

sub proxy_conn () {
    my $access_log = defined $main::access_log ? 
        $main::access_log : $main::logdir . "access_log";
    open ACCESSFILE, "<", $access_log or die "access_log not found at [$access_log]\n\n";
    while (<ACCESSFILE>) {
        $_ =~ /"CONNECT.+?"/;
        my $line = $&;
        chomp $line;
        $main::proxy{$line} += 1;
    }
    close ACCESSFILE;

    &print_hash_count(\%main::proxy);
    
}

#Author: Ian McCown
#Apache Log Project part 4

sub access_denied () {
    my $audit_log = defined $main::audit_log ? 
        $main::audit_log : $main::logdir . "audit_log";
    open AUDITFILE, "<", $audit_log or die "audit_log not found at [$audit_log]\n\n";
    while (<AUDITFILE>) {
            $_ =~ /mod_security-message:.*\. /;
            my $line = $';
            chomp $line;
            $main::denied{$line} += 1;
    }
    close AUDITFILE;

    &print_hash_count(\%main::denied);
}

#Author: Jeff Bean
#Apache Log Project part 4


sub brute() {
    my $audit_log = defined $main::audit_log ? 
        $main::audit_log : $main::logdir . "audit_log";
    open AUDITFILE, "<", $audit_log or die "audit_log not found at [$audit_log]\n\n";
    my @all = <AUDITFILE>;
    close AUDITFILE;
    
    my $joined = join " ", @all;
    my @each_request = split("============================", $joined);

    foreach (@each_request) {
        $_ =~ /Request:.*GET.*config.*(login=.*passwd.*? )/;

        my $line = $&;
        my @vals = split("&", $1);
        my @name =  split("=", $vals[0]);
        my @passwd = split("=", $vals[1]);
        my @request = split(" ", $line);
        if ($_ =~ /\"passwd\=\" at THE_REQUEST./ and $request[1] ne "") {
            $main::brute_requests{$request[1]}->{$name[1]} = $passwd[1];
        }
    }
    

    foreach my $ipkey ( keys %main::brute_requests) {
        print "Attackers IP address: [$ipkey]\n" if not $main::fileflag;
        print $main::outfile localtime() . "    Attackers IP address: [$ipkey]\n" if $main::fileflag;
        while ( my ($key, $val) = each %{ $main::brute_requests{$ipkey} }) {
            print "Username:Password => $key:$val\n" if not $main::fileflag;
            print $main::outfile localtime() . "    Username:Password => $key:$val\n" if $main::fileflag;
        }
        last;
    }
}


#Author: Ian McCown
#Apache Log Project part 6

sub users () {
    my $audit_log = defined $main::audit_log ? 
        $main::audit_log : $main::logdir . "audit_log";
    open AUDITFILE, "<", $audit_log or die "audit_log not found at [$audit_log]\n\n";
    while (<AUDITFILE>) {
        $_ =~ /Authorization: Basic /;
        my $decoded = decode_base64($');
        if ($decoded ne ":") {
            my @split = split(":", $decoded);
            $main::users{$split[0]} = $split[1];
        }
    }
    close AUDITFILE;

    foreach (keys %main::users) {
        printf "%3s:$main::users{$_}\n", ($_) if not $main::fileflag;
        print $main::outfile localtime() . "    $_:$main::users{$_}\n" if $main::fileflag;
    }
}

#Author: Ian McCown
#Apache Log Project part 7

sub malicious_activity () {
    my $ip = "";
    my $newline = "false";
    my $audit_log = defined $main::audit_log ? 
    $main::audit_log : $main::logdir . "audit_log";
    open AUDITFILE, "<", $audit_log or die "audit_log not found at [$audit_log]\n\n";
    while (<AUDITFILE>) {
        if (/============================/) {
            $newline = "true";
        }
            elsif (/Request: /) {
            $_ =~ /Request: [0-9]+\.[0-9]+\.[0-9]+\.[0-9]+/;
            $& =~ /Request: /;
            $ip = $';
        }
        elsif ($_ =~ /email/ && $newline) {
            $main::spam{$ip} ++;
            $newline = "false";
        }
        elsif ($_ =~ /default\.ipa/ && $newline) {
            $main::codered{$ip} ++;
            $newline = "false";
        }
        elsif ($_ =~ /[root\.exe]|[httpodbc\.dll]/ && $newline) {
            $main::nimda{$ip} ++;
            $newline = "false";
        }
        elsif ($_ =~ /Nessus/) {
            print "$_\n" if not $main::fileflag;
            print $main::outfile localtime() . "    $_\n" if $main::fileflag;
        }

    }
    close AUDITFILE;
    
    print "Suspected Email Spammers:\n" if not $main::fileflag;
    print $main::outfile localtime() . "    Suspected Email Spammers:\n" if $main::fileflag;
    &print_hash_count(\%main::spam);
    print "Suspected CodeRed Alerts (references to default.ipa):\n" if not $main::fileflag;
    print $main::outfile localtime() . "    Suspected CodeRed Alerts (references to default.ipa):\n" if $main::fileflag;
    &print_hash_count(\%main::codered);
    print "Suspected NIMDA Entries (references to root.exe or hrrpodbc.dll):\n" if not $main::fileflag;
    print $main::outfile localtime() . "    Suspected NIMDA Entries (references to root or cmd.exe):\n" if $main::fileflag;
    &print_hash_count(\%main::nimda);
}

return(1);